//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <ddk.h>
#include <compoundChannel.h>
#include "usbTrans.h"

static IDeviceDriver *g_pUSBDev = NULL;
static DzMutex g_usb_send_mutex;
static DzMutex g_usb_recv_mutex;

#define UCDC_INIT           0x0000D001
#define UCDC_STOP           0x0000D002
#define UCDC_WAKE           0x0000D003
#define UCDC_SET_SYNC       0x0000D004
#define UCDC_SET_ASYNC      0x0000D005
#define UCDC_SET_PRIF       0x0000D006
#define UCDC_CLR_BUF        0x0000D007
#define UDCD_WAIT_EVENT     0xA000D001
#define UDCD_SET_EVENT      0xA000D002

#define UVCP_SIGNAL_OUT     0x08001FFF
#define UVCP_RX_CHAR        0x80001000
#define UVCP_ENQ_FAIL       0x80001002

#define CTRL_DISABLECONSOLE  0x0B
#define CTRL_ENABLECONSOLE   0x0C

//extern int g_LogicChannelConnected;

Int32 USBInitPort()
{
    MemoryBuf_<1> memBuf;
    IDeviceDriver *pConsolDev = NULL;
    ECode ec;
    ec = DzFindService(L"device:console0", (IInterface **)&(pConsolDev));

    if (FAILED(ec)) {
        kprintf("Cann't find console service!\n");
        return -1;
    }

    ec = DzFindService(
        L"device:usbser", (IInterface **)&(g_pUSBDev));
    if (FAILED(ec)) {
        kprintf("Cann't find device:usbser service!\n");
        return -1;
    }

    ec = g_pUSBDev->Control(UCDC_STOP, memBuf, NULL, NULL);
    if (FAILED(ec)) {
        kprintf("Cann't Stop UDC Transmit!\n");
        return -1;
    }

    ec = g_pUSBDev->Control(UCDC_CLR_BUF, memBuf, NULL, NULL);
    if (FAILED(ec)) {
        kprintf("Cann't clear UDC buffer!\n");
        return -1;
    }

//    ec = g_pUSBDev->Control(UCDC_SET_SYNC, memBuf, NULL, NULL);
//    if (FAILED(ec)) {
//        kprintf("Cann't set to synchronous!\n");
//        return -1;
//    }

    ec = g_pUSBDev->Control(UCDC_WAKE, memBuf, NULL, NULL);
    if (FAILED(ec)) {
        kprintf("Cann't Wake UDC Transmit!\n");
        return -1;
    }

    return 0;
}

int USBSendData(void* pData, int size, int *pSendSize)
{
    WaitResult wr;
    MemoryBuf memBuf((Byte*)pData, size);
    int nSendSize = 0;

    g_usb_send_mutex.Lock(&wr);
    ECode ec = g_pUSBDev->Write(0, memBuf, &nSendSize, NULL);
    g_usb_send_mutex.Unlock();

    if (FAILED(ec)) {
        kprintf("Write Usb Failed\n");
        return -1;
    }

    if (NULL != pSendSize) {
        *pSendSize = nSendSize;
    }

    return 0;
}

int USBReceiveData(void* pData, int size, int *pReceiveSize)
{
    WaitResult wr;
    ECode ec;
    MemoryBuf tempBuf((Byte *)pData, size);

    g_usb_recv_mutex.Lock(&wr);
    ec = g_pUSBDev->Read(0, size, &tempBuf, NULL);
    g_usb_recv_mutex.Unlock();

    if (FAILED(ec)) {
        kprintf("Cann't get Usb data \n");
        return -1;
    }

    if (NULL != pReceiveSize) {
        *pReceiveSize = tempBuf.GetUsed();
    }

    return 0;
}
